package by.andronix.logger
{
	import caurina.transitions.Tweener;
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TextEvent;
	import flash.text.engine.FontPosture;
	import flash.text.engine.Kerning;
	import flashx.textLayout.compose.StandardFlowComposer;
	import flashx.textLayout.container.ContainerController;
	import flashx.textLayout.container.ScrollPolicy;
	import flashx.textLayout.edit.SelectionManager;
	import flashx.textLayout.elements.Configuration;
	import flashx.textLayout.elements.FlowElement;
	import flashx.textLayout.elements.ParagraphElement;
	import flashx.textLayout.elements.SpanElement;
	import flashx.textLayout.elements.TextFlow;
	import flashx.textLayout.events.CompositionCompleteEvent;
	import flashx.textLayout.events.FlowOperationEvent;
	import flashx.textLayout.events.UpdateCompleteEvent;
	import flashx.textLayout.formats.TextAlign;
	import flashx.textLayout.formats.TextLayoutFormat;
	import flashx.textLayout.formats.VerticalAlign;
	import flashx.textLayout.formats.WhiteSpaceCollapse;
	import mx.core.mx_internal;
	import mx.core.UIComponent;
	import mx.logging.targets.LineFormattedTarget;
	
	
	
	
	use namespace mx_internal;

	public class ScreenOverlayTarget extends LineFormattedTarget
	{
		
		public static var clip:DisplayObjectContainer;
		private static var _instance:ScreenOverlayTarget;
		private static var _textFlow:TextFlow;
		private static var _containerController:ContainerController;
		
		private static const TYPE_COLORS:Object = {
											info: 0x77FF77,
											debug: 0xFFFFFF,
											warn: 0xFFFF44,
											error: 0xFF5555,
											fatal: 0xFF5555,
		
											xml_dump_1: 0xFFCC00,
											xml_dump_2: 0x77FF77,
											object_dump: 0xAAAAFF };
											
											
											
		public static function toggle():void {
			if (_instance && clip) {
				_instance.toggleView();
			}
		}
		
		//======================================================================================================
		
		public function ScreenOverlayTarget()
		{
			super();
			
			_instance = this;
			
			if (clip) throw( new Error('ScreenOverlayTarget should be initialized only once!') );
			
			initClip();
		}
		
		private function initClip():void {
			
			clip = new UIComponent();			
			clip.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
			
			clip.mouseChildren = false;
			clip.mouseEnabled = false;
			clip.contextMenu = null;
			clip.alpha = 0;
			
			var bg:Sprite = new Sprite();
			var content:Sprite = new Sprite();
			
			var g:Graphics = bg.graphics;
			
			g.clear();
			
			g.beginFill(0, 0.8);
				g.drawRect(0, 0, 1920, 768);
			g.endFill();
			
			g.lineStyle(2, 0x444444, 0.8);
			g.moveTo(0, 0);
			g.lineTo(1920, 0);
			
			clip.addChild(bg);
			clip.addChild(content);
						
			//TLF
			var _tlfConfig:Configuration = new Configuration();
			var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat();
			textLayoutFormat.color = 0xFFFFFF;
			//textLayoutFormat.renderingMode = RenderingMode.CFF;
			textLayoutFormat.fontFamily = 'Courier New';
			textLayoutFormat.fontSize = 12;
			textLayoutFormat.kerning = Kerning.ON;
			textLayoutFormat.fontStyle = FontPosture.NORMAL;			
			textLayoutFormat.textAlign = TextAlign.LEFT;
			textLayoutFormat.verticalAlign = VerticalAlign.TOP;
			textLayoutFormat.whiteSpaceCollapse = WhiteSpaceCollapse.COLLAPSE;				
			_tlfConfig.textFlowInitialFormat = textLayoutFormat;					
			
			_textFlow = new TextFlow(_tlfConfig);
			
			_textFlow.flowComposer = new StandardFlowComposer();
			
			var sm:SelectionManager = new SelectionManager();	
			//_textFlow.interactionManager = sm;	
			
			
			_textFlow.paddingTop = 8;
			_textFlow.paddingBottom = 8;
			_textFlow.paddingLeft = 8;
			_textFlow.paddingRight = 8;
						
			_textFlow.whiteSpaceCollapse = WhiteSpaceCollapse.COLLAPSE;	
			
			_containerController = new ContainerController(content, 1920, 768);
			_containerController.verticalScrollPolicy = ScrollPolicy.ON;
			_textFlow.flowComposer.addController(_containerController);		
			
			_textFlow.addEventListener(CompositionCompleteEvent.COMPOSITION_COMPLETE, onCompositionComplete);
			_textFlow.addEventListener(UpdateCompleteEvent.UPDATE_COMPLETE, onUpdateComplete);
			_textFlow.addEventListener(FlowOperationEvent.FLOW_OPERATION_END, onFlowOperationEnd);
			
			//end TLF			
			
		}
		
		private function addedToStage(evt:Event):void {
			
			trace('ScreenOverlayTarget addedToStage');
			
			
		}
		
		private function linkHandler(evt:TextEvent):void {
			
			trace(evt);
			
			switch(evt.text) {
				case 'clear':
					var fe:FlowElement = _textFlow.getChildAt(0);
					
					while ( fe ) {
						
						_textFlow.removeChild(fe);
						
						fe = _textFlow.getChildAt(0);
						
					}
					
					_textFlow.flowComposer.updateAllControllers();

				break;
			}
		}
		
		protected function toggleView(evt:Event=null):void {
			
			var toShow:Boolean = !clip.visible;
			
			if (toShow) {
				clip.alpha = 0;
				clip.visible = true;
			}
			
			Tweener.addTween(clip, {alpha: toShow ? 1 : 0, 
									time: .5,
									onComplete: function():void { clip.visible = false; }
								});
			
		}
		
		
		private function onUpdateComplete(evt:UpdateCompleteEvent):void {
			
			//var textRect:Rectangle = _containerController.getContentBounds();
			
			//_containerController.verticalScrollPosition = textRect.height;
			
		}
		
		private function onCompositionComplete(evt:CompositionCompleteEvent):void {	
			
			
			
		}
		
		private function onFlowOperationEnd(evt:FlowOperationEvent):void {
			
			
		}
		
		
		override mx_internal function internalLog(message:String):void
		{
			
			var msgType:String = message.match(/\[(WARN|ERROR|FATAL|DEBUG|INFO)\]/)[1];
			msgType = msgType.toLowerCase();
			
			msgType = msgType == 'fatal' ? 'error' : msgType;
			
			
			var span:SpanElement = new SpanElement();
			span.text = message;
			
			span.color = TYPE_COLORS[msgType];
			
			//check xml or object dump
			if ( message.search('<modules>') != -1 ) {
				
				span.color = TYPE_COLORS['xml_dump_2'];
				
			} else if ( message.search('<config>') != -1 ) {
				
				span.color = TYPE_COLORS['xml_dump_1'];
				
			} else if ( message.search(/\((Object|Array)\)#/) != -1 ) {
				
				span.color = TYPE_COLORS['object_dump'];
				
			}
			
			var para:ParagraphElement = new ParagraphElement();
			para.addChild( span );
						
			_textFlow.addChildAt(0, para);
			
			_textFlow.flowComposer.updateAllControllers();
		}
		
	}
}